import argparse

import win32clipboard as w
import win32con
import win32api
import win32gui
import time
from apscheduler.schedulers.blocking import BlockingScheduler
import datetime
import os
import requests
import sys
import ctypes
# import ntplib
import pyautogui
import subprocess

Venue1 = "1号场地"
Venue2 = "2号场地"
Venue3 = "3号场地"
# "BFEBFBFF000A0653" 工位电脑
GONGWEI_MACHINE="BFEBFBFF000A0653"
# "BFEBFBFF00090675" 12100
MACHINE_12100="BFEBFBFF00090675"
# "BFEBFBFF000306C3" 4790
MACHINE_4790 = "BFEBFBFF000306C3"
def move_to_top(name = 'SSTap Beta 1.0.9.7 - 享受游戏'):
    def get_all_hwnd(hwnd, mouse):
        if (win32gui.IsWindow(hwnd) and
                win32gui.IsWindowEnabled(hwnd) and
                win32gui.IsWindowVisible(hwnd)):
            hwnd_map.update({hwnd: win32gui.GetWindowText(hwnd)})

    hwnd_map = {}
    win32gui.EnumWindows(get_all_hwnd, 0)

    for h, t in hwnd_map.items():
        print(h, t)
        if t:
            if t == name:
                # h 为想要放到最前面的窗口句柄
                print(h)

                win32gui.BringWindowToTop(h)
                # shell = win32com.client.Dispatch("WScript.Shell")
                # shell.SendKeys('%')

                # 被其他窗口遮挡，调用后放到最前面
                win32gui.SetForegroundWindow(h)

                # 解决被最小化的情况
                win32gui.ShowWindow(h, win32con.SW_RESTORE)

                return h

# 把文字放入剪贴板
def setText(aString):
    w.OpenClipboard()
    w.EmptyClipboard()
    w.SetClipboardData(win32con.CF_UNICODETEXT, aString)
    w.CloseClipboard()


# 模拟ctrl+V
def ctrlV():
    win32api.keybd_event(17, 0, 0, 0)  # ctrl
    win32api.keybd_event(86, 0, 0, 0)  # V
    win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)  # 释放按键
    win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)


# 模拟alt+s
def altS():
    win32api.keybd_event(18, 0, 0, 0)
    win32api.keybd_event(83, 0, 0, 0)
    win32api.keybd_event(83, 0, win32con.KEYEVENTF_KEYUP, 0)
    win32api.keybd_event(18, 0, win32con.KEYEVENTF_KEYUP, 0)


# 模拟enter
def enter():
    win32api.keybd_event(13, 0, 0, 0)
    win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)


# 模拟单击
def click():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)


# 移动鼠标的位置
def movePos(x, y):
    win32api.SetCursorPos((x, y))
def log_string(log, string):
    # message = str(time.strftime("%Y-%m-%d %H:%M:%S.%f'", time.localtime()))+"  "+string
    message = str( datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) + "  " + string
    log.write(message+ '\n')
    log.flush()
    print(message)

def create_path(dir):
    if not os.path.exists(dir):
        os.makedirs(dir)


def get_cpu_serial_number():
    result = subprocess.run(['wmic', 'cpu', 'get', 'ProcessorID', '/format:value'], capture_output=True, text=True)
    output = result.stdout
    for line in output.split('\n'):
        if 'ProcessorId=' in line:
            return line.split('=')[1].strip()





def findDict(day_of_week,fields):
    x=0
    y=0
    startX=1564
    startY=284
    gap=72
    if (day_of_week == 6 or day_of_week == 1) and (fields[0] == Venue2 or fields[0] == Venue3) and fields[1] == 20:
        x = startX;
        y = startY + gap * 0
    if day_of_week == 2 and fields[0] == Venue3 and fields[1] == 22:
        x = startX;
        y = startY + gap * 0
    if day_of_week == 2 and fields[0] == Venue2 and fields[1] == 22:
        x = startX;y = startY + gap * 2

    if day_of_week == 3 and (fields[0]  == Venue1 or fields[0]== Venue3 ) and fields[1] == 19:
        x = startX;y = startY + gap * 1
    if day_of_week == 3 and (fields[0]  == Venue1 or fields[0]== Venue3 ) and fields[1] == 20:
        x = startX;y = startY + gap * 2
    if day_of_week == 3 and fields[0] == Venue2 or fields[0] == Venue3 and fields[1] == 20:
        x = startX;y = startY + gap * 0

    #周六的1,2，，周日的1,2,3场地
    if ((day_of_week == 4 or day_of_week == 5) and (fields[1] == 9)):
        x = startX;y = startY + gap * 1
    if ((day_of_week == 4 or day_of_week == 5) and (fields[1] == 10)):
        x = startX; y = startY + gap * 2
    if ((day_of_week == 4 or day_of_week == 5) and (fields[1] == 11)):
        x = startX; y = startY + gap * 3

    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1]==12:
        x=startX;y=startY+gap*3
    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1]==13:
        x=startX;y=startY+gap*4

    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1]==16:
        x=startX;y=startY+gap*7
    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1]==17:
        x=startX;y=startY+gap*8
    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1] == 18:
        x = startX;y = startY + gap * 9
    if (((day_of_week==4 or day_of_week==5) and (fields[0]==Venue1 or fields[0]==Venue2)) or (day_of_week==5 and fields[0]==Venue3)) and fields[1] == 19:
        x = startX;y = startY + gap * 10

    if day_of_week == 4  and fields[0] == Venue3 and fields[1] == 18:
        x = startX;y = startY + gap * 5
    if day_of_week == 4 and fields[0] == Venue3 and fields[1] == 19:
        x = startX;y = startY + gap * 6

    return x,y

def book_cmd(fields):


    today = str(time.strftime("%Y-%m-%d", time.localtime()))
    log_path = 'logs'
    create_path(log_path)
    log = open(log_path + "/{}_log.txt".format(today),"a")
    h = move_to_top("微信")


    cpu_serial_number = get_cpu_serial_number()


    # 没找到微信则打开微信
    if(h == None):
        try:
            exe_path = r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"
            win32api.ShellExecute(0, 'open', exe_path, '', '', 1)
        except:
            exe_path = r"C:\Program Files\Tencent\WeChat\WeChat.exe"
            win32api.ShellExecute(0, 'open', exe_path, '', '', 1)

        time.sleep(1)
        move_to_top("微信")
    # print(h)


    # 获取鼠标当前位置
    # hwnd=win32gui.FindWindow("MozillaWindowClass",None)
    hwnd = win32gui.FindWindow("WeChatMainWndForPC", None)
    win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
    win32gui.MoveWindow(hwnd, 0, 0, 1000, 700, True)

    # 移动到聊天,防止出错后直接在通信录的搜索框
    movePos(28, 147)
    time.sleep(0.5)
    click()
    time.sleep(0.5)

    time.sleep(0.5)
    # 1.移动鼠标到通讯录位置，单击打开通讯录
    movePos(28, 147)
    time.sleep(0.5)
    click()
    time.sleep(0.5)
    # 2.移动鼠标到搜索框，单击，输入要搜索的名字
    movePos(148, 35)
    time.sleep(0.5)
    click()

    today = datetime.datetime.today()
    day_of_week = today.weekday()+1

    admin_name = "文件传输助手"



    # fields=[[Venue3,12],[Venue2,13]]

    fieldsLen=len(fields)




    log_string(log, admin_name)
    setText(admin_name)
    time.sleep(0.5)
    ctrlV()
    time.sleep(1)  # 别问我为什么要停1秒，问就是给微信一个反应的时间，他反应慢反应不过来，其他位置暂停的原因同样
    enter()
    time.sleep(1)


    wechatBrowserCloseX=1897
    wechatBrowserCloseY = 12
    if cpu_serial_number==GONGWEI_MACHINE:
        LabelX = 781
        LabelY = 497
    elif cpu_serial_number==MACHINE_12100:
        LabelX = 744
        LabelY = 509
    else: #4790
        LabelX = 705
        LabelY = 504

    firstLabelX=237
    firstLabelY = 13
    secondLabelX = 460
    secondLabelY = 13

    submitButtonX=966
    submitButtonY = 914
    ensureButtonX=1040
    ensureButtonY = 134

    filedSelectX = 1031
    filedSelectY = 111
    ensureX = 953
    ensureY = 948

    centerDownSelectX=947
    centerDownSelectY = 802

    daySelectX = 1017
    daySelectY = 179

    dayDownSelectX = 1585
    dayDownSelectY = 802


    #点击链接,并删除所有的窗口
    movePos(LabelX, LabelY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)
    movePos(wechatBrowserCloseX, wechatBrowserCloseY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)

    # 点击链接
    movePos(LabelX, LabelY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)




    #如果要约两个场地
    if fieldsLen>1:
        # 切换回去微信
        pyautogui.hotkey('alt', 'tab')
        # 再次点击链接
        movePos(LabelX, LabelY)
        time.sleep(2)

        # 再次点击链接
        movePos(LabelX, LabelY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)

    # 点击第一个链接
    movePos(firstLabelX, firstLabelY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)


    # 加载完成需要比较长的时间
    for i in range(10, -1, -1):
        log_string(log, "休眠" + str(i))
        time.sleep(1)

    # 选择场地
    # 1号场地，则什么都不敢
    log_string(log, str(fields))
    if fields[0][0]==Venue1:
        pass
    else: #2,3号场地先点击一下选择场地
        log_string(log,"filedSelect")
        movePos(filedSelectX, filedSelectY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)

        #2号场地就啥都不弄
        if fields[0][0] == Venue2:
            pass
        else:
            #3号场地就要点击一次下选
            movePos(centerDownSelectX, centerDownSelectY)
            time.sleep(0.5)
            click()
            time.sleep(0.5)
        #点击确定
        movePos(ensureX, ensureY)
        time.sleep(0.5)
        click()
        time.sleep(3) #加载需要一定时间


    # 加载完成需要比较长的时间
    for i in range(5, -1, -1):
        log_string(log, "休眠" + str(i))
        time.sleep(1)

    # 选择日期
    movePos(daySelectX, daySelectY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)
    #有可能有跨月的情况存在
    movePos(centerDownSelectX, centerDownSelectY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)
    #点击2次到后天
    movePos(dayDownSelectX, dayDownSelectY)
    time.sleep(0.5)
    click()
    time.sleep(1)
    #点击2次到后天
    movePos(dayDownSelectX, dayDownSelectY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)
    #点击确定
    movePos(ensureX, ensureY)
    time.sleep(0.5)
    click()
    time.sleep(3) #加载需要一定时间


    #选择时间段
    x,y=findDict(day_of_week,fields[0])
    if x!=0 and y!=0:
        # 对应的时间段
        movePos(x, y)
        time.sleep(0.5)
        click()
        time.sleep(0.5)
        log_string(log, "等待提交 " + str(fields[0]))
    else:
        log_string(log,"时间段错误，时间段没记录 "+str(fields[0]))


    #点击第二个标签
    if fieldsLen > 1:
        movePos(secondLabelX, secondLabelY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)

        # 选择场地
        # 1号场地，则什么都不敢
        log_string(log, str(fields))
        if fields[1][0] == Venue1:
            pass
        else:  # 2,3号场地先点击一下选择场地
            log_string(log, "filedSelect")
            movePos(filedSelectX, filedSelectY)
            time.sleep(0.5)
            click()
            time.sleep(0.5)

            # 2号场地就啥都不弄
            if fields[1][0] == Venue2:
                pass
            else:
                # 3号场地就要点击一次下选
                movePos(centerDownSelectX, centerDownSelectY)
                time.sleep(0.5)
                click()
                time.sleep(0.5)
            # 点击确定
            movePos(ensureX, ensureY)
            time.sleep(0.5)
            click()
            time.sleep(3) #加载需要一定时间

        # 加载完成需要比较长的时间
        for i in range(2, -1, -1):
            log_string(log, "休眠" + str(i))
            time.sleep(1)

        # 选择日期
        movePos(daySelectX, daySelectY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)
        # 有可能有跨月的情况存在
        movePos(centerDownSelectX, centerDownSelectY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)
        # 点击2次到后天
        movePos(dayDownSelectX, dayDownSelectY)
        time.sleep(0.5)
        click()
        time.sleep(1)
        # 点击2次到后天
        movePos(dayDownSelectX, dayDownSelectY)
        time.sleep(0.5)
        click()
        time.sleep(0.5)
        # 点击确定
        movePos(ensureX, ensureY)
        time.sleep(0.5)
        click()
        time.sleep(3) #加载需要一定时间

        # 选择时间段
        x, y = findDict(day_of_week, fields[1])
        if x != 0 and y != 0:
            # 对应的时间段
            movePos(x, y)
            time.sleep(0.5)
            click()
            time.sleep(0.5)
            log_string(log, "等待提交 " + str(fields[1]))
        else:
            log_string(log, "时间段错误，时间段没记录 " + str(fields[1]))



    #移动到第一个标签
    movePos(firstLabelX, firstLabelY)
    time.sleep(0.5)
    # 提交按钮
    movePos(submitButtonX, submitButtonY)
    time.sleep(0.5)
    # 点击提交按钮
    click()
    time.sleep(0.5)
    # 移动到确认预定
    movePos(ensureButtonX, ensureButtonY)
    time.sleep(0.5)

    cnt = 10
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
    while True:

        response = requests.get("http://vv.video.qq.com/checktime?otype=json", headers=headers)
        flag = True
        if response.status_code == 200:
            text = response.text
            jsonContent = text[13:-1]
            # print(jsonContent)
            if text is not None:
                dict = eval(jsonContent)
                if "t" in dict:
                    flag = False
                    # print(dict)
                    now_time = datetime.datetime.fromtimestamp(dict["t"])
                    # print(now_time)
        if flag:
            now_time = datetime.datetime.now()
        cur_time = now_time.hour * 3600 + now_time.minute * 60 + now_time.second + now_time.microsecond / 1000000  # microsecond是微妙,转换为秒

        # log_string(log, str(now_time))
        # 等待时间00
        # 6500-M2,这个时间估计每台电脑都不一样?
        # if cur_time >= 8 * 3600 + 0*60 + bias_time:
        # bias_time = -1.5#七点59分 -1
        # if cur_time >= 17 * 3600 + 28 * 60 + 2:
        if cur_time >= 8 * 3600 + 0 * 60 + 0.5:
            # time.sleep(0.2)#休眠200MS，防止时间对不上
            now_time = datetime.datetime.now()
            log_string(log, "click " + str(now_time))
            # time.sleep(1)
            break
        else:
            time.sleep(0.1)
            if cnt>20:
                log_string(log, "waiting...")
                cnt=0
        # time.sleep(10)
        cnt+=1




    # # 加载完成需要比较长的时间
    # for i in range(3, -1, -1):
    #     log_string(log, "休眠" + str(i))
    #     time.sleep(1)

    # 点击动到确认预定
    click()
    # for i in range(2):
    #     time.sleep(0.2)
    #     click()

    if fieldsLen > 1:
        # 移动到第2个标签
        movePos(secondLabelX, secondLabelY)
        time.sleep(0.2)
        click()
        # 提交按钮
        movePos(submitButtonX, submitButtonY)
        time.sleep(0.2)
        click()
        # 确认预定
        movePos(ensureButtonX, ensureButtonY)

        # # 加载完成需要比较长的时间
        # for i in range(3, -1, -1):
        #     log_string(log, "休眠" + str(i))
        #     time.sleep(1)

        for i in range(5):
            time.sleep(0.2)
            click()

    #成后就要退出，关闭
    movePos(wechatBrowserCloseX, wechatBrowserCloseY)
    time.sleep(0.5)
    click()
    time.sleep(0.5)


    return 1


# today = str(time.strftime("%Y-%m-%d", time.localtime()))
# log_path = 'logs'
# create_path(log_path)
# log = open(log_path + "/{}_log.txt".format(today),"a")
# while True:
#     time.sleep(0.01)
#     log_string(log, "waiting...")
# for i in range(10):
#     import pyautogui
#     pyautogui.hotkey('win', 'd')
#     time.sleep(5)
#     book_cmd_old()
#     time.sleep(5)

# book_cmd([[Venue3, 22],[Venue2, 22]])
# exit()

if __name__ == "__main__":


    code_version = 20240809
    print(os.getcwd())
    print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    print("file name: %s" % (__file__), ", code Version: ", code_version)

    # time.sleep(10)
    # exit()
    parser = argparse.ArgumentParser()
    parser.add_argument('--user', default="zfr", type=str)
    args = parser.parse_args()

    scheduler = BlockingScheduler()

    cpu_serial_number = get_cpu_serial_number()

    if cpu_serial_number==GONGWEI_MACHINE:
        pass
        # scheduler.add_job(func=book_cmd, args=([[Venue1, 16], [Venue1, 17]],),
        #                   trigger='cron', day_of_week=4 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周4约周6
    elif cpu_serial_number==MACHINE_12100:
        scheduler.add_job(func=book_cmd, args=([[Venue2, 20]],),
                          trigger='cron', day_of_week=3 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周3约周5
        # scheduler.add_job(func=book_cmd, args=([[Venue2, 16], [Venue2, 17]],),
        #                   trigger='cron', day_of_week=4 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周4约周6
        scheduler.add_job(func=book_cmd, args=([[Venue2, 10], [Venue2, 11]],),
                          trigger='cron', day_of_week=4 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周4约周6

        scheduler.add_job(func=book_cmd, args=([[Venue3, 19], [Venue3, 18]],),
                          trigger='cron', day_of_week=5 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周5约周7
    else: #4790
        scheduler.add_job(func=book_cmd, args=([[Venue3, 19]],),
                          trigger='cron', day_of_week=3 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周3约周5
        scheduler.add_job(func=book_cmd, args=([[Venue3, 10], [Venue3, 11]],),
                          trigger='cron', day_of_week=4 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周4约周6
        scheduler.add_job(func=book_cmd, args=([[Venue2, 19], [Venue2, 18]],),
                          trigger='cron', day_of_week=5 - 1, hour=7, minute=50, misfire_grace_time=60 * 5)  # 周5约周7

    scheduler.start()
    # book_cmd()